package com.qinggeng.project.system.service.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Maps;
import com.qinggeng.common.enums.OrdersTypeEnum;
import com.qinggeng.common.enums.PrintStatusEnum;
import com.qinggeng.common.enums.ShowTypeEnum;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.project.api.dto.Draw;
import com.qinggeng.project.api.dto.DrawResult;
import com.qinggeng.project.api.dto.GiftReturn;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.api.utils.OrdersCheckUtils;
import com.qinggeng.project.system.domain.*;
import com.qinggeng.project.system.domain.json.ActiveTime;
import com.qinggeng.project.system.domain.json.GiftConfig;
import com.qinggeng.project.system.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import static com.qinggeng.project.system.domain.GoodsGift.FREE_GIFT_CONFIG_KEY;

@Service
public class GiftServiceImpl implements IGiftService {

    public static final String NUMBER_RANGE_KEY="sys.gift.numberRange";

    public static final String DRAW_RULE_KEY="sys.gift.drawRule";

    public static final String DRAW_TIMES_KEY="sys.gift.drawTimes";

    public static final String ACTIVE_TIME_KEY="sys.gift.activeTime";

    public static final String DRAW_URL_KEY="sys.gift.drawUrl";

    public static final String OUT_PRINT_TIME_KEY="sys.orders.outPrintTime";

    public static final String OUT_PAY_TIME_KEY="sys.orders.outPayTime";


    @Autowired
    private IGoodsGiftService goodsGiftService;
    @Autowired
    private ISysConfigService sysConfigService;
    @Autowired
    private IGoodsPercentService goodsPercentService;
    @Autowired
    private IOrdersService ordersService;
    @Autowired
    private MQSendService mqSendService;
    @Autowired
    private IAssistRecordService assistRecordService;
    @Autowired
    private IOrdersGiftService ordersGiftService;
    @Autowired
    private OrdersCheckUtils ordersCheckUtils;
    @Autowired
    private UserAccountRecordOrderSingleItemService orderSingleItemService;


    @Override
    public Orders checkIsDraw(Long ordersId){
        //检验订单支付状态
        Orders orders=ordersCheckUtils.checkOrdersPayStatus(ordersId,ApiUtils.getUserId());

        if(orders.getOrdersType().equals(OrdersTypeEnum.免费送.getValue())
                ||orders.getOrdersType().equals(OrdersTypeEnum.捶一捶.getValue())
                ||orders.getOrdersType().equals(OrdersTypeEnum.好友助力.getValue())){
            throw new CustomException("您已参与过其他活动，不可同时参与抽奖！",ShowTypeEnum.用户.getValue());
        }
        if(!orders.getPrintStatus().equals(PrintStatusEnum.不可打印.getStatus())){
            throw new CustomException("抽奖已超时", ShowTypeEnum.用户.getValue());
        }
        Integer drawTimes=goodsPercentService.getDrawTimes(orders);
        if(drawTimes<1){
            throw new CustomException("您还没有参与抽奖的资格！", ShowTypeEnum.用户.getValue());
        }
        return orders;
    }
    @Override
    public Orders checkIsFree(Long ordersId){
        //检验是否具备抽奖资格
        Orders orders=this.checkIsDraw(ordersId);
        if(orders.getTotalPrice().compareTo(getFreeDrawPrice())<0){
            throw new CustomException("您尚未具备免单抽奖的资格",ShowTypeEnum.用户.getValue());
        }
        return orders;
    }

    @Override
    public Draw getDrawTimes(Orders orders){
        //检验订单支付状态
        ordersCheckUtils.checkOrderStatus(orders);
        Draw draw=new Draw();
        draw.setOrdersId(orders.getOrdersId());
        String drawUrl=sysConfigService.getConfigValue(DRAW_URL_KEY);
        if(orders.getTotalPrice().compareTo(getFreeDrawPrice())>=0){
            draw.setIsFree(true);
            draw.setDrawTimes(1);
            draw.setDrawUrl(drawUrl);
            return draw;
        }
        draw.setIsFree(false);
        //根据商品分类获取订单抽奖次数
        Integer drawTimes=goodsPercentService.getDrawTimes(orders);
        if(drawTimes<1){
            draw.setDrawTimes(0);
            return draw;
        }
        //抽奖链接地址
        draw.setDrawUrl(drawUrl);
        draw.setDrawTimes(drawTimes);
        return draw;
    }



    @Override
    public Map<Integer,GoodsGift> getLuckyNum(List<GoodsGift> goodsGiftList, String numberRange){

        //随机产生中奖号码
        Map<Integer,GoodsGift> luckyNumMap= Maps.newHashMap();
        Long loseGiftId = goodsGiftService.getLoseGiftId();
        for (GoodsGift gift:goodsGiftList) {
            if(gift.getGiftId().compareTo(loseGiftId)==0){
                continue;
            }
            int maxSize=luckyNumMap.size()+(new BigDecimal(numberRange).multiply(gift.getProbability())).intValue();
            while(luckyNumMap.size()<maxSize){
                Integer luckyNum=(int)(Math.random()*Integer.parseInt(numberRange));
                if(luckyNumMap.containsKey(luckyNum)){
                    continue;
                }
                luckyNumMap.put(luckyNum,gift);
            };
        }
        return luckyNumMap;
    }
    @Override
    public DrawResult getDrawResult(UserWishGift userWishGift){
        if(null==userWishGift){
            return new DrawResult();
        }
        DrawResult result=new DrawResult();
        result.setTimes(userWishGift.getDrawTimes());
        result.setGifts(goodsGiftService.selectGoodsGiftList(userWishGift));
        return result;
    }

    @Override
    public DrawResult getOrdersDrawResult(UserWishGift userWishGift,Map<Integer,GoodsGift> luckyNum, Integer drawNum){

        DrawResult result=this.getDrawResult(userWishGift);
        //未中奖
        if(!luckyNum.containsKey(drawNum)){
            result.setIsWin(false);
            return result;
        }
        GoodsGift winGift=luckyNum.get(drawNum);
        //普通抽奖
        if(userWishGift.getDrawType()==0){
            //奖品库存不足
            if(!goodsGiftService.checkGoodsGiftNum(winGift.getGiftId())){
                result.setIsWin(false);
                return result;
            }
        }
        //10=未领取
        OrdersGift ordersGift=ordersGiftService.insertOrdersGift(userWishGift.getOrdersId(),winGift,"10");
        if(null==ordersGift){
            result.setIsWin(false);
            return result;
        }

        result.setIsWin(true);
        result.setWinGift(ordersGift);

        //发送中奖弹幕消息
        mqSendService.sendLuckyDrawAsynMessage(ApiUtils.getUserId(),winGift.getGiftName());

        return result;
    }

    @Override
    public DrawResult getAssistDrawResult(AssistRecord record, Map<Integer,GoodsGift> luckyNum,Integer drawNum){

        //中奖结果
        if(!luckyNum.containsKey(drawNum)){
            return new DrawResult(false);
        }
        GoodsGift winGift=luckyNum.get(drawNum);
        //更新助力记录
        record.setIsWin(true);
        record.setGiftId(winGift.getGiftId());
        if (assistRecordService.updateAssistRecord(record)<1) {
            return new DrawResult(false);
        }

        DrawResult result=new DrawResult();
        result.setIsWin(true);
        result.setWinGift(new OrdersGift(winGift, 1L));
        //发送中奖弹幕消息
        mqSendService.sendLuckyDrawAsynMessage(ApiUtils.getUserId(),winGift.getGiftName());
        return result;
    }
    @Override
    public  Boolean getIsActive(){
        //读取抽奖活动时间段配置文件
        String activeTimeJson=sysConfigService.getConfigValue(ACTIVE_TIME_KEY);
        ActiveTime activeTime= JSON.parseObject(activeTimeJson,ActiveTime.class);
        //抽奖活动开始时间
        Calendar startTime=getCalendar(activeTime.getStartTime().getHour(),activeTime.getStartTime().getMinute());
        //抽奖活动结束时间
        Calendar endTime=getCalendar(activeTime.getEndTime().getHour(),activeTime.getEndTime().getMinute());
        //当前时间
        Date now= DateUtils.getNowDate();
        return now.after(startTime.getTime())&&now.before(endTime.getTime());
    }


    /**
     * 根据时间获取日历实例
     * @param hour
     * @param minute
     * @return
     */
    private Calendar getCalendar(Integer hour,Integer minute){
        Calendar calendar=Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY,hour);
        calendar.set(Calendar.MINUTE,minute);
        return calendar;
    }

    private BigDecimal getFreeDrawPrice(){
        String freeGiftConfigJson=sysConfigService.getConfigValue(FREE_GIFT_CONFIG_KEY);
        GiftConfig freeGiftConfig=JSON.parseObject(freeGiftConfigJson,GiftConfig.class);
        return freeGiftConfig.getDrawPrice();
    }


    @Override
    public Boolean checkIsReturn(Date ordersTime) {

        //获取用户参与抽奖的订单退款金额和时间
        GiftReturn giftReturn = orderSingleItemService.getGiftReturnByUserId();
        if (giftReturn != null && giftReturn.getReturnTime() != null) {
            //计算用户从第一次抽奖订单退款到目前的未退款订单总额
            BigDecimal totalPrice = ordersService.getOrdersTotalPrice(giftReturn.getReturnTime(),ordersTime);
            //如果退款金额大于消费金额
            return giftReturn.getReturnPrice() != null && giftReturn.getReturnPrice().compareTo(totalPrice) > 0;
        }
        return false;
    }


}
